﻿using System;
using System.Drawing;
using System.Windows.Forms;
using PowerMonitor.ModbusDev;
using PowerMonitor.BaseCtrl;
using PowerMonitor.Properties;

namespace PowerMonitor
{
    public partial class ShowComunication : baseDockForm
    {
        public delegate void delDisRxTxMsg(msgInfo msg);///报文显示

        private readonly string strRootName = "SysDevList";
        //private string _strRootText = Resources.txtMeterList;
        private int iChlId = -1;
        private int iDevId = -1;
        public int IChlId
        {
            get { return iChlId; }
            //set { iChlId = value; }
        }
        public int IDevId
        {
            get { return iDevId; }
            //set { iDevId = value; }
        }
        private object LockHelper = new object();
        public ShowComunication()
        {
            InitializeComponent();
        }

        private void ShowComunication_Load(object sender, EventArgs e)
        {
            RefreshChlTree();
        }
        public bool RefreshChlTree()
        {
            TreeNode tn = null;
            int ChlCnt = 0;

            tvDevices.Nodes.Clear(); // 清空所有
            TreeNode RootNode = new TreeNode(Resources.txtMeterList);//_strRootText
            RootNode.Name = strRootName;
            RootNode.ImageIndex = 1;
            RootNode.SelectedImageIndex = 0;
            for (int i = 0; i < AppMain.ChlList.Count; i++)
            {
                tn = new TreeNode();
                ChlCnt++;
                tn.Name = AppMain.ChlList[i].baseChlPara.ChannelId.ToString();// 通道名称 以及 装置名称 均使用ID(ChlId DevId)作为标识
                tn.Text = AppMain.ChlList[i].baseChlPara.ChannelName;         // 显示名称可自定义
                RefreshDevTree(ref tn, AppMain.ChlList[i]);       // 初始化通道下的装置名称列表
                RootNode.Nodes.Add(tn);
            }
            tvDevices.Nodes.Add(RootNode);
            tvDevices.ExpandAll();
            if (ChlCnt == 0)
            {
                return false;
            }
            else
            {
                if (tvDevices.TopNode != null && tvDevices.TopNode.Nodes.Count > 0 && tvDevices.TopNode.FirstNode.Nodes.Count > 0)
                {
                    tvDevices.SelectedNode = tvDevices.TopNode.Nodes[0].FirstNode;
                    tvDevices_AfterSelect(null, new TreeViewEventArgs(tvDevices.TopNode.FirstNode.FirstNode));
                }
                return true;
            }
        }
        private bool RefreshDevTree(ref TreeNode node,Channel Chl)
        {
            InnerModbusChannel tempChl = null;
            if (Chl is InnerModbusChannel)
            {
                tempChl = Chl as InnerModbusChannel;
            }
            
            if (tempChl != null)
            {
                for (int j = 0; j < tempChl.m_DeviceList.Count; j++)
                {
                    node.Nodes.Add(tempChl.m_DeviceList[j].DeviceId.ToString(), tempChl.m_DeviceList[j].Name);
                }
            }
            else
            {
                return false;
            }
            return true;
        }

        private void dgvComMsg_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
        {
            SolidBrush b = new SolidBrush(this.dgvComMsg.RowHeadersDefaultCellStyle.ForeColor);
            e.Graphics.DrawString((e.RowIndex + 1).ToString(System.Globalization.CultureInfo.CurrentUICulture), this.dgvComMsg.DefaultCellStyle.Font,
                                   b, e.RowBounds.Location.X + 15, e.RowBounds.Location.Y + 4);
        }
        private bool isFrozen = false;
        private void tsmiFrozenMsg_Click(object sender, EventArgs e)
        {
            if (isFrozen)
            {
                tsmiFrozenMsg.Image = Properties.Resources._lock;
                tsmiFrozenMsg.Text = Resources.txtFrozenMsg;
            } 
            else
            {
                tsmiFrozenMsg.Image = Properties.Resources.unlock;
                tsmiFrozenMsg.Text = Resources.txtCancelFrozenMsg;
            }
            isFrozen = !isFrozen;
        }

        bool isClear = false;
        private void tsmiClearMsg_Click(object sender, EventArgs e)
        {
            isClear = true;
        }

        /// <summary>
        /// 显示收发内容
        /// </summary>
        /// <param name="DataIndex"></param>
        public void DisplayTxRxMsg(msgInfo DisMsg)
        {
            lock (LockHelper)
            {
                if (isFrozen) // 停止更新
                {
                    return;
                }
                if (!this.Visible)
                {
                    isClear = true;
                    return;
                }
                if (isClear)
                {
                    isClear = false;
                    dgvComMsg.Rows.Clear();
                }
                msgInfo DispInfo = (msgInfo)DisMsg;
                string strID = "";
                if (iChlId < 0 && iDevId < 0)  // 根据选中节点显示报文
                {
                    return;
                }
                else if (iChlId >= 0 && iDevId == -1 && iChlId != DispInfo.chlId) // 通道数据
                {
                    return;
                }
                else if (iDevId >= 0 && (iChlId != DispInfo.chlId || iDevId != DispInfo.devId)) // 装置数据
                {
                    return;
                }
                if (iDevId >= 0)
                {
                    strID = "C"+iChlId.ToString("D2") + "_D" + iDevId.ToString("D2");
                }
                else
                {
                    strID = "C" + iChlId.ToString("D2");
                }
                
                if (int.Parse(dgvComMsg.Tag.ToString()) == 0) // 冻结控件  不再更新显示
                {
                    return;
                }
                if (dgvComMsg.Rows.Count > 500)
                {
                    dgvComMsg.Rows.RemoveAt(0);
                }
                dgvComMsg.Rows.Add();
                DataGridViewRow CurRow = null;
                try
                {
                    CurRow = dgvComMsg.Rows[dgvComMsg.Rows.Count - 2];
                    if (dgvComMsg.FirstDisplayedScrollingRowIndex != -1) // 自动隐藏时
                    {
                        dgvComMsg.FirstDisplayedScrollingRowIndex = dgvComMsg.Rows.Count - 2;
                    }
                }
                catch
                {
                    return;
                }
                switch (DispInfo.msgType)
                {
                    case eMsgType.msgSend:
                        CurRow.Cells[0].Value = strID + Resources.txtSend;
                        CurRow.Cells[1].Value = DispInfo.sendtime.ToString("HH:mm:ss:fff");
                        CurRow.DefaultCellStyle.BackColor = Color.PowderBlue;
                        break;
                    case eMsgType.msgReceiveOK:
                        CurRow.Cells[0].Value = strID + Resources.txtReceive;
                        CurRow.Cells[1].Value = DispInfo.elapse.ToString() + "ms";
                        CurRow.DefaultCellStyle.BackColor = Color.LightGreen;
                        break;
                    case eMsgType.msgInsSend:
                        CurRow.Cells[0].Value = strID + Resources.txtSend;
                        CurRow.Cells[1].Value = DispInfo.sendtime.ToString("HH:mm:ss:fff");
                        CurRow.DefaultCellStyle.BackColor = Color.LightYellow;
                        break;
                    case eMsgType.msgInsReceiveOK:
                        CurRow.Cells[0].Value = strID + Resources.txtReceive;
                        CurRow.Cells[1].Value = DispInfo.elapse.ToString() + "ms";
                        CurRow.DefaultCellStyle.BackColor = Color.GreenYellow;
                        break;
                    case eMsgType.msgReceiveFail:
                        CurRow.Cells[0].Value = strID + Resources.txtReceive;
                        CurRow.Cells[1].Value = DispInfo.elapse.ToString() + "ms";
                        CurRow.DefaultCellStyle.BackColor = Color.LightGreen;//Color.IndianRed;
                        break;
                    case eMsgType.msgInsReceiveFail:
                        CurRow.Cells[0].Value = strID + Resources.txtReceive;
                        CurRow.Cells[1].Value = DispInfo.elapse.ToString() + "ms";
                        CurRow.DefaultCellStyle.BackColor = Color.LightGreen;//Color.Tomato;
                        break;
                    default:
                        CurRow.Cells[0].Value = strID + Resources.txtSend;
                        CurRow.Cells[1].Value = DispInfo.sendtime.ToString("HH:mm:ss:fff");
                        CurRow.DefaultCellStyle.BackColor = Color.PowderBlue;
                        break;
                }

                string strMsg = "", strTemp;
                if (DispInfo.msgBytes != null)
                {
                    for (int i = 0; i < DispInfo.msgBytes.Length; i++)
                    {
                        strTemp = (DispInfo.msgBytes[i].ToString("X02") + "  ");
                        strMsg += strTemp;
                    }
                    CurRow.Cells[2].Value = strMsg;
                }
                else
                {
                    CurRow.Cells[2].Value = " ";//"无报文";
                }
            }  
        }

        /// <summary>
        /// 设备选择
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tvDevices_AfterSelect(object sender, TreeViewEventArgs e)
        {
            try
            {
                AppMain.msgQueue.Clear(); // 清空报文队列
                if (tvDevices.SelectedNode.Name == strRootName || tvDevices.SelectedNode == null) // 固定名称
                {
                    iChlId = -1;
                    iDevId = -1;
                }
                else if (tvDevices.SelectedNode.Parent.Name == strRootName)
                {
                    for (int i = 0; i < AppMain.ChlList.Count; i++)
                    {
                        if (tvDevices.SelectedNode.Name == AppMain.ChlList[i].baseChlPara.ChannelId.ToString())
                        {
                            iChlId = AppMain.ChlList[i].baseChlPara.ChannelId;
                            iDevId = -1;
                            break;
                        }
                    }
                }
                else
                {
                    iDevId = GetDevIdFromSelNode(tvDevices.SelectedNode);
                }
                isClear = true;
            }
            catch (System.Exception ex)
            {
                System.Diagnostics.Trace.WriteLine(ex.Message);
            }
        }
        /// <summary>
        /// 从节点获取设备号  选中节点不是设备则是-1
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        private int GetDevIdFromSelNode(TreeNode node)
        {
            InnerModbusChannel tempChl = null;
            for (int i = 0; i < AppMain.ChlList.Count; i++)  // 寻找通道
            {
                if (tvDevices.SelectedNode.Parent.Name == AppMain.ChlList[i].baseChlPara.ChannelId.ToString())
                {
                    if (AppMain.ChlList[i] is InnerModbusChannel)
                    {
                        tempChl = AppMain.ChlList[i] as InnerModbusChannel;
                    }
                    if (tempChl == null)
                    {
                        return -1;
                    }
                    iChlId = i;
                    break;
                }
            }
            if (tempChl == null)
            {
                return -1;
            }
            for (int j = 0; j < tempChl.m_DeviceList.Count; j++)  // 寻找对应设备
            {
                if (tvDevices.SelectedNode.Name == tempChl.m_DeviceList[j].DeviceId.ToString())
                {
                    return tempChl.m_DeviceList[j].DeviceId;
                }
            }
            return -1;
        }

        private void ShowComunication_Activated(object sender, EventArgs e)
        {
            //RefreshChlTree();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (AppMain.msgQueue.Count > 0)
            {
                DisplayTxRxMsg(AppMain.msgQueue.Dequeue());
            }
            if (AppMain.msgQueue.Count > 50)
            {
                AppMain.msgQueue.Clear();
            }
        }
    }
    public struct msgInfo
    {
        public int chlId;  // 通道号
        public int devId;  // 设备号
        public long elapse; // 耗费时间
        public byte[] msgBytes;
        public eMsgType msgType;
        public DateTime sendtime;
    }
    public enum eMsgType
    {
        msgSend,            // 轮询
        msgReceiveOK,
        msgReceiveFail,
        msgInsSend,         // 插帧
        msgInsReceiveOK,
        msgInsReceiveFail,
    }
}
